package com.hhxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhxy.constants.SystemConstants;
import com.hhxy.handler.exception.CustomException;
import com.hhxy.mapper.MenuMapper;
import com.hhxy.model.dto.AddMenuDto;
import com.hhxy.model.entity.Menu;
import com.hhxy.model.vo.MenuVo;
import com.hhxy.model.vo.RoutersVo;
import com.hhxy.service.MenuService;
import com.hhxy.utils.BeanCopyUtils;
import com.hhxy.utils.SecurityUtils;
import com.hhxy.utils.convert.MenuConverter;
import com.hhxy.utils.response.AppHttpCodeEnum;
import com.hhxy.utils.response.ResponseResult;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ghp
 * @description 针对表【tb_menu(菜单权限表)】的数据库操作Service实现
 * @createDate 2023-04-25 11:58:49
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu>
        implements MenuService {

    /**
     * 根据用户userId查询权限信息
     *
     * @return
     */
    @Override
    public List<String> selectPermsByUserId() {
        // 判断当前用户是否是超级管理员
        if (SecurityUtils.isAdmin()) {
            // 是超级管理员，直接返回所有权限
            // 查询出所有的菜单信息（所有为菜单或按钮的权限信息，且处于正常状态，目录不需要， 因为目录只是用于展示，不涉及到操作）
            List<Menu> menuList = this.list(new LambdaQueryWrapper<Menu>()
                    .in(Menu::getMenuType, SystemConstants.MENU_TYPE_MENU, SystemConstants.MENU_TYPE_BUTTON)
                    .eq(Menu::getStatus, SystemConstants.MENU_STATUS_NORMAL));
            // 获取菜单信息中的权限信息
            List<String> perms = menuList.stream()
                    .map(Menu::getPerms)
                    .collect(Collectors.toList());
            return perms;
        }
        // 不是超级管理员，则只返回所具有的权限
        return getBaseMapper().selectPermsByUserId(SecurityUtils.getUserId());
    }

    /**
     * 根据userId查询菜单信息
     *
     * @return
     */
    @Override
    public ResponseResult selectRouterMenuTreeByUserId() {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = null;
        //判断是否是管理员
        if (SecurityUtils.isAdmin()) {
            // 如果是，则获取所有符合要求的Menu
            menus = menuMapper.selectAllRouterMenu();
        } else {
            // 否则获取当前用户所具有的Menu
            menus = menuMapper.selectRouterMenuTreeByUserId(SecurityUtils.getUserId());
        }
        // 将查询到的数据构建成 tree 的形式
        //先找出第一层的菜单，然后去找他们的子菜单设置到children属性中
        List<Menu> menuList = MenuConverter.builderMenuTree(menus, 0L);

        // 封装VO
        List<MenuVo> menuVoList = BeanCopyUtils.copyBeanList(menuList, MenuVo.class);
        for (Menu menu : menuList) {
            for (MenuVo menuVo : menuVoList) {
                if (menu.getId().equals(menuVo.getId())) {
                    List<MenuVo> children = BeanCopyUtils.copyBeanList(menu.getChildren(), MenuVo.class);
                    menuVo.setChildren(children);
                }
            }
        }
        return ResponseResult.okResult(new RoutersVo(menuVoList));
    }


    /**
     * 分页条件查询菜单信息
     *
     * @param menuName
     * @param status
     * @return
     */
    @Override
    public ResponseResult list(String menuName, String status) {
        // 分页条件查询出菜单信息
        List<Menu> menuList = this.list(new LambdaQueryWrapper<Menu>()
                .like(StringUtils.hasText(menuName), Menu::getMenuName, menuName)
                .eq(StringUtils.hasText(status), Menu::getStatus, status)
                .orderByAsc(Menu::getOrderNum)
                .orderByDesc(Menu::getUpdateTime));
        // 封装VO
        List<MenuVo> menuVos = BeanCopyUtils.copyBeanList(menuList, MenuVo.class);
        return ResponseResult.okResult(menuVos);
    }

    /**
     * 新增菜单
     *
     * @param addMenuDto
     * @return
     */
    @Override
    public ResponseResult add(AddMenuDto addMenuDto) {
        Menu menu = BeanCopyUtils.copyBean(addMenuDto, Menu.class);
        // TODO 数据校验
        boolean flag = this.save(menu);
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_INSERT_ERROR);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS_INSERT);
    }

    /**
     * 根据id删除菜单
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult deleteMenuById(Long id) {
        // 先判断该菜单下是否有子菜单
        int count = this.count(new LambdaQueryWrapper<Menu>()
                .eq(Menu::getParentId, id));
        if (count > 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CLIENT_MENU_ERROR);
        }

        // 该菜单下不存在子菜单，直接删除
        boolean flag = this.removeById(id);
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_DELETE_ERROR);
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS_DELETE);
    }

    /**
     * 更新菜单信息
     *
     * @param addMenuDto
     * @return
     */
    @Override
    public ResponseResult updateMenuById(AddMenuDto addMenuDto) {
        Menu menu = BeanCopyUtils.copyBean(addMenuDto, Menu.class);
        boolean flag = this.updateById(menu);
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_UPDATE_ERROR);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS_UPDATE);
    }

    /**
     * 获取对应角色的权限信息
     *
     * @param id
     * @return
     */
    @Override
    public List<Long> selectMenuListByRoleId(Long id) {
        // 判断是否是超级管理员
        if (SystemConstants.SUPER_ADMIN.equals(id)) {
            // 是超级管理员就返回所有的菜单id（超级管理员勾选所有的权限）
            return this.getBaseMapper().selectAllMenuList();
        }
        return this.getBaseMapper().selectMenuListByRoleId(id);
    }

}




